import React, { useEffect, useState, useRef } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { ConvexGeometry } from 'three/addons/geometries/ConvexGeometry.js';
import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';


const CameraController: React.FC = () => {
  const mountRef = useRef<HTMLDivElement>(null);
  const sceneRef = useRef<THREE.Scene | null>(null);
  const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);
  const rendererRef = useRef<THREE.WebGLRenderer | null>(null);
  const groupRef = useRef<THREE.Group | null>(null);
  const animationIdRef = useRef<number>(0);

  const useCamera = () => {
    const [cameraPosition, setCameraPosition] = useState<THREE.Vector3>(
      new THREE.Vector3(15, 20, 30)
    );
    // 创建一个 Vector3 对象用于存储方向向量
    const [cameraDirection, setCameraDirection] = useState<THREE.Vector3>(
      new THREE.Vector3()
    );

    const [cameraRotation, setCameraRotation] = useState<THREE.Euler>(
      new THREE.Euler()
    );


    useEffect(() => {
      const animate = () => {
        if (cameraRef.current) {
          setCameraPosition(cameraRef.current.position.clone());
          let direction = new THREE.Vector3();
          cameraRef.current.getWorldDirection(direction);
          setCameraDirection(direction);
          setCameraRotation(cameraRef.current.rotation.clone());
          (window as any).setCameraTransform(
            // {x: cameraRef.current.position.x, y: cameraRef.current.position.y, z: cameraRef.current.position.z},
            { x: 6.61, y: 2.36, z: -15 },
            {x: cameraRef.current.rotation.x*360/Math.PI, y: cameraRef.current.rotation.y*360/Math.PI, z: cameraRef.current.rotation.z*360/Math.PI},
            cameraRef.current.fov
          );
        }
        return requestAnimationFrame(animate);
      };
      let animateid = animate();
      return () => cancelAnimationFrame(animateid);
    }, []);

    return {
      'position': cameraPosition,
      'direction': cameraDirection,
      'rotation': cameraRotation,
    }
  };

  useEffect(() => {
    const container = mountRef.current;
    if (!container) return;

    // 初始化场景
    const scene = new THREE.Scene();
    sceneRef.current = scene;

    // 初始化渲染器
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(container.clientWidth, container.clientHeight);
    container.appendChild(renderer.domElement);
    rendererRef.current = renderer;

    // 初始化相机
    const camera = new THREE.PerspectiveCamera(
      40,
      container.clientWidth / container.clientHeight,
      1,
      1000
    );
    camera.position.set(10, 10, 10);
    scene.add(camera);
    cameraRef.current = camera;

    // 初始化控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.minDistance = 20;
    controls.maxDistance = 50;
    controls.maxPolarAngle = Math.PI / 2;

    // 添加光照
    scene.add(new THREE.AmbientLight(0x666666));
    const light = new THREE.PointLight(0xffffff, 3, 0, 0);
    camera.add(light);

    // 添加辅助工具
    scene.add(new THREE.AxesHelper(20));

    // 创建主组
    const group = new THREE.Group();
    scene.add(group);
    groupRef.current = group;

    // 创建点云几何体
    const initialGeometry = new THREE.DodecahedronGeometry(10);
    initialGeometry.deleteAttribute('normal');
    initialGeometry.deleteAttribute('uv');
    
    // 修复类型错误：将结果视为 BufferGeometry
    const mergedGeometry = BufferGeometryUtils.mergeVertices(
      initialGeometry
    ) as THREE.BufferGeometry;

    const vertices: THREE.Vector3[] = [];
    const positionAttribute = mergedGeometry.getAttribute('position');

    for (let i = 0; i < positionAttribute.count; i++) {
      const vertex = new THREE.Vector3();
      vertex.fromBufferAttribute(positionAttribute, i);
      vertices.push(vertex);
    }

    // 创建点云材质和几何体
    const textureLoader = new THREE.TextureLoader();
    textureLoader.load('https://threejs.org/examples/textures/sprites/disc.png', (texture) => {
      texture.colorSpace = THREE.SRGBColorSpace;
      
      const pointsMaterial = new THREE.PointsMaterial({
        color: 0x0080ff,
        map: texture,
        size: 1,
        alphaTest: 0.5
      });

      const pointsGeometry = new THREE.BufferGeometry().setFromPoints(vertices);
      const points = new THREE.Points(pointsGeometry, pointsMaterial);
      group.add(points);

      // 创建凸包网格
      const meshMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff,
        opacity: 0.5,
        side: THREE.DoubleSide,
        transparent: true
      });

      const meshGeometry = new ConvexGeometry(vertices);
      const mesh = new THREE.Mesh(meshGeometry, meshMaterial);
      group.add(mesh);
    });

    // 窗口大小调整处理
    const handleResize = () => {
      if (!cameraRef.current || !rendererRef.current || !container) return;
      cameraRef.current.aspect = container.clientWidth / container.clientHeight;
      cameraRef.current.updateProjectionMatrix();
      rendererRef.current.setSize(container.clientWidth, container.clientHeight);
    };

    window.addEventListener('resize', handleResize);

    // 动画循环
    const animate = () => {
      animationIdRef.current = requestAnimationFrame(animate);
      if (groupRef.current) {
        groupRef.current.rotation.y += 0.005;
      }
      renderer.render(scene, camera);
    };

    animate();

    // 清理函数
    return () => {
      window.removeEventListener('resize', handleResize);
      cancelAnimationFrame(animationIdRef.current);
      
      if (rendererRef.current) {
        rendererRef.current.dispose();
      }
      
      if (container.contains(renderer.domElement)) {
        container.removeChild(renderer.domElement);
      }
      
      // 手动释放几何体和材质资源
      scene.traverse((object) => {
        if (object instanceof THREE.Mesh || object instanceof THREE.Points) {
          if (object.geometry) object.geometry.dispose();
          if (object.material) {
            if (Array.isArray(object.material)) {
              object.material.forEach(material => material.dispose());
            } else {
              object.material.dispose();
            }
          }
        }
      });
    };
  }, []);

  return (
    <div>
      <div ref={mountRef} style={{ width: '100%', height: '80vh' }} />;
      <div>
        <div>
          相机位置:
          <div>
            x: {useCamera()['position'].x.toFixed(2)}
            y: {useCamera()['position'].y.toFixed(2)}
            z: {useCamera()['position'].z.toFixed(2)}
          </div>
        </div>
        <div>
          相机朝向:
          <div>
            x: {useCamera()['direction'].x.toFixed(2)}
            y: {useCamera()['direction'].y.toFixed(2)}
            z: {useCamera()['direction'].z.toFixed(2)}
          </div>
        </div>
        <div>
          相机旋转:
          <div>
            x: {useCamera()['rotation'].x.toFixed(2)}
            y: {useCamera()['rotation'].y.toFixed(2)}
            z: {useCamera()['rotation'].z.toFixed(2)}
          </div>
        </div>
      </div>
    </div>
  )
};

export default CameraController;
